package com.fufu.thread;

/**
 * 线程同步
 * @author: BlcakTiger
 * @date: 2023/2/11 19:53
 * @contact: hsf6661@163.com
 */
public class ThreadSync {

    /**
     * 多线程同时读写共享变量时，会造成逻辑错误，因此需要通过synchronized同步；
     * 同步的本质就是给指定对象加锁，加锁后才能继续执行后续代码；
     * 注意加锁对象必须是同一个实例；
     * 对JVM定义的单个原子操作不需要同步。
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {

        Thread th1 = new Thread(()->{
            for (int i = 0; i < 200; i++) {
                //synchronized锁的对象可以是任意对象，jvm判断根据对象判断是否为同一把锁
                //synchronized阻止了线程的并发性，降低了效率，也就是会降低性能
                //对于原子操作不需要加锁，但对于非原子操作，为了保证数据的安全性，通常需要加锁
                synchronized (Counter.lock) {
                    Counter.count += 1;
                }
            } 
        });

        Thread th2 = new Thread(()->{
            for (int i = 0; i < 200; i++) {
                synchronized(Counter.lock) {
                    Counter.count -= 1;
                }
            }
        });

        th1.start();
        th2.start();
        th1.join();
        th2.join();
        System.out.println(Counter.count);
    }


}

/**
 * 计数器
 */
class Counter{
    public final static Object lock = new Object();
    public static int count = 0;
}
